#include "../include/head.h"
//用户注册
int user_register(socket_t fd_client, MYSQL *mysql){
    train_t train;
    char username[256] = {0};
    char salt[256] = {0};
    char encrypted_password[256] = {0};
    int ret = -1;
    //接收客户端发送的用户名
    bzero(&train, sizeof(train_t));
    recv(fd_client, &train.data_length, sizeof(int), 0);
    recv(fd_client, train.data, train.data_length, 0);
    strcpy(username, train.data);
    printf("用户名%s\n", username);
    //判断数据库表中没有同名用户，返回随机生成的盐值
    ret = getInfo_user(mysql, username, salt, encrypted_password);
    printf("ret = %d\n", ret);
    if(ret == 1){//证明用户名已经被注册
                 //返回注册失败信息
        bzero(&train, sizeof(train_t));
        train.data_length = 0;
        send(fd_client, &train.data_length, sizeof(int), 0);
        printf("该用户名已经被注册!\n");
        return -1;
    }
    //新用户名可用，生成随机盐值并发送给客户端
    bzero(salt, sizeof(salt));
    ret = generate_salt(salt);
    printf("盐值%s\n", salt);
    bzero(&train, sizeof(train_t));
    train.data_length = strlen(salt);
    printf("盐值长度%d\n", train.data_length);
    strcpy(train.data, salt);
    send(fd_client, &train.data_length, sizeof(int), 0);
    send(fd_client, train.data, train.data_length, 0);

    //接收客户端发来的用盐值sha512生成的密文
    bzero(&train, sizeof(train_t));
    bzero(encrypted_password, sizeof(encrypted_password));
    recv(fd_client, &train.data_length, sizeof(int), MSG_WAITALL);
    recv(fd_client, train.data, train.data_length, MSG_WAITALL);
    strcpy(encrypted_password, train.data);

    //调用add_user()添加新用户的信息，并返回成功注册信号;
    ret = add_user(mysql, username, salt, encrypted_password);
    if (ret == -1) {
        printf("添加新用户失败\n");
        // 没有给客户端反馈
        bzero(&train, sizeof(train_t));
        train.tag = TAG_ERROR;
        sprintf(train.data, "注册失败，请换一个用户名\n");
        train.data_length = strlen(train.data);
        send(fd_client, &train.tag, sizeof(int), 0);
        send(fd_client, &train.data_length, sizeof(int), 0);
        send(fd_client, train.data, train.data_length, 0);
        return -1;
    }
    bzero(&train, sizeof(train_t));
    train.tag = TAG_RESPONSEREGISTER;
    sprintf(train.data, "用户[%s]注册成功！\n", username);
    train.data_length = strlen(train.data);
    send(fd_client, &train.tag, sizeof(int), 0);
    send(fd_client, &train.data_length, sizeof(int), 0);
    send(fd_client, train.data, train.data_length, 0);
    printf("用户[%s]注册成功！\n", username);

    return 0;
}

//用户登录
int user_login(socket_t fd_client, MYSQL *mysql, userInfo_t *user_info){
    //用户注册
    train_t train;
    char username[256] = {0};
    char salt[256] = {0};
    char encrypted_password[256] = {0};
    int ret = -1;
    //接收客户端发送的用户名
    bzero(&train, sizeof(train_t));
    recv(fd_client, &train.data_length, sizeof(int), 0);
    recv(fd_client, train.data, train.data_length, MSG_WAITALL);
    strcpy(username, train.data);
    //判断数据库表中有没有该用户，返回随机生成的盐值
    ret = getInfo_user(mysql, username, salt, encrypted_password);
    if(ret == -1){//用户不存在
                  //返回登录失败信息
        bzero(&train, sizeof(train_t));
        train.data_length = 0;
        send(fd_client, &train.data_length, sizeof(int), 0);
        printf("该用户不存在!\n");
        return -1;
    }
    //用户名存在，发送用户盐值给客户端
    bzero(&train, sizeof(train_t));
    train.data_length = strlen(salt);
    strcpy(train.data, salt);
    send(fd_client, &train.data_length, sizeof(int), 0);
    send(fd_client, train.data, train.data_length, 0);

    //接收客户端发来的用盐值sha512生成的密文
    bzero(&train, sizeof(train_t));
    recv(fd_client, &train.data_length, sizeof(int), MSG_WAITALL);
    recv(fd_client, train.data, train.data_length, MSG_WAITALL);
    if(strcmp(encrypted_password, train.data) != 0){
        //用户密码和数据库中密码不匹配，登录失败，返回失败信息
        bzero(&train, sizeof(train_t));
        train.tag = TAG_ERROR;
        sprintf(train.data, "用户[%s]登录失败>_<\n", username);
        train.data_length = strlen(train.data);
        send(fd_client, &train.tag, sizeof(int), 0);
        send(fd_client, &train.data_length, sizeof(int), 0);
        send(fd_client, train.data, train.data_length, 0);
        printf("用户[%s]登录失败>_<！\n", username);
        return -1;
    }

    //用户登录成功，返回登录成功的信息
    bzero(&train, sizeof(train_t));
    train.tag = TAG_RESPONSELOGIN;
    sprintf(train.data, "用户[%s]登录成功！\n", username);
    train.data_length = strlen(train.data);
    send(fd_client, &train.tag, sizeof(int), 0);
    send(fd_client, &train.data_length, sizeof(int), 0);
    send(fd_client, train.data, train.data_length, 0);
    printf("用户[%s]登录成功！\n", username);

    // 登录成功，发送用户当前目录
    strcpy(user_info->username, username);
    strcpy(user_info->current_path, "/");
    strcat(user_info->current_path, username);

    return 0;
}
//用户注销
int user_cancel(socket_t fd_client, MYSQL *mysql){
    train_t train;
    char username[256] = {0};
    char salt[256] = {0};
    char encrypted_password[256] = {0};
    int ret = -1;
    //接收客户端发送的用户名
    bzero(&train, sizeof(train_t));
    recv(fd_client, &train.data_length, sizeof(int), 0);
    recv(fd_client, train.data, train.data_length, 0);
    strcpy(username, train.data);
    //判断数据库表中有没有该用户，返回随机生成的盐值
    ret = getInfo_user(mysql, username, salt, encrypted_password);
    if(ret == -1){//用户不存在
                  //返回用户验证失败信息
        bzero(&train, sizeof(train_t));
        train.data_length = 0;
        send(fd_client, &train.data_length, sizeof(int), 0);
        printf("该用户不存在!\n");
        return -1;
    }

    //用户名存在，发送用户盐值给客户端
    bzero(&train, sizeof(train_t));
    train.data_length = strlen(salt);
    strcpy(train.data, salt);
    send(fd_client, &train.data_length, sizeof(int), 0);
    send(fd_client, train.data, train.data_length, 0);

    //接收客户端发来的用盐值sha512生成的密文
    bzero(&train, sizeof(train_t));
    recv(fd_client, &train.data_length, sizeof(int), MSG_WAITALL);
    recv(fd_client, train.data, train.data_length, MSG_WAITALL);
    if(strcmp(encrypted_password, train.data) != 0){
        //用户密码和数据库中密码不匹配，返回验证失败信息
        bzero(&train, sizeof(train_t));
        train.tag = TAG_ERROR;
        send(fd_client, &train.tag, sizeof(int), 0);
        printf("用户[%s]身份验证失败>_<！\n", username);
        return -1;
    }

    //用户登录成功，执行用户注销操作，返回注销结果
    ret = cancel_user(mysql, username);
    bzero(&train, sizeof(train_t));
    train.tag = TAG_RESPONSECANCEL;
    send(fd_client, &train.tag, sizeof(int), 0);
    printf("用户[%s]已注销>_<\n", username);

    return 0;
}
//随机生成盐值
int generate_salt(char *salt){
    srand(time(NULL));
    char RNG_Array[65] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
    int count = SALTLENGTH;
    strcat(salt, "$6$");
    while(count > 0){
        int idx = rand()%64;
        strncat(salt, RNG_Array + idx, 1);
        --count;
    }
    strcat(salt, "$");
    return 0;
}

